package com.jy.importclient.support;

import com.jy.importclient.common.constants.ExpConstants;
import com.jy.importclient.common.constants.ReqConstants;
import com.jy.importclient.common.dto.StartTaskDto;
import com.jy.importclient.common.dto.VerifyFile;
import com.jy.importclient.common.enums.TaskStatusEnum;
import com.jy.importclient.common.util.FileUtil;
import com.jy.importclient.common.util.StringUtil;
import com.jy.importclient.common.vo.ReturnVo;
import com.jy.importclient.entity.ImportSubTask;
import com.jy.importclient.entity.ImportTaskLog;
import com.jy.importclient.handler.AbsReqSqlldrHandler;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * @类名 SubTaskSupport
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/5/8 23:06
 * @版本 1.0
 */
@Slf4j
@Component
public class SubTaskSupport {

    @Resource
    private HttpSupport httpSupport;

    @Resource
    private AbsReqSqlldrHandler handler;

    public boolean verifyDatFile(ImportTaskLog importTaskLog, String filePath, VerifyFile verFile, Long id) throws IOException {
        //获取dat文件内容，并校验能否获取dat文件
        String datFileContext;
        try {
            datFileContext = FileUtil.getFile(filePath + "/" + verFile.getDatFileName(), ExpConstants.DAT_FILE_NOT_EXISTS_EXP);
        } catch (Exception e) {
            importTaskLog.setFilePath(filePath);
            importTaskLog.setEndTime(new Date());
            importTaskLog.setTaskStatus(String.valueOf(TaskStatusEnum.FAIL.getCode()));
            String errorMsg = ExpConstants.DAT_FILE_NOT_EXISTS_EXP;
            importTaskLog.setErrorMsg(errorMsg);
            httpSupport.send(ReturnVo.error(errorMsg)
                            .put("id", id)
                            .put("importTaskLog", importTaskLog)
                            .put("flag", "retry")
            );
            log.info("校验失败,原因是:{}", importTaskLog.getErrorMsg());
            return false;
        }

        //执行dat文件的记录行数和文件大小校验，并生成日志
        Map<String, Object> checkMap = FileUtil.check(datFileContext, filePath + "/" + verFile.getDatFileName(), verFile);
        if (checkMap.get("flag").equals(false)) {
            importTaskLog.setFilePath(filePath);
            importTaskLog.setEndTime(new Date());
            importTaskLog.setTaskStatus(String.valueOf(TaskStatusEnum.FAIL.getCode()));
            String errorMsg = String.valueOf(checkMap.get("msg"));
            importTaskLog.setErrorMsg(errorMsg);
            importTaskLog.setExpCode((Integer) checkMap.get("code"));
            httpSupport.send(ReturnVo.error(errorMsg)
                            .put("id", id)
                            .put("importTaskLog", importTaskLog)
                            .put("flag", "retry")
            );
            log.info("校验失败,原因是:{}", importTaskLog.getErrorMsg());
            return false;
        }
        return true;
    }

    public boolean importDatFile(String ctlFileName, ImportSubTask importSubTask, String filePath, ImportTaskLog importTaskLog, String datFileName) throws SchedulerException {
        //构建请求参数
        String ctlPath = filePath + "/file_ctl/" + ctlFileName;
        String cmd_params_str = ReqConstants.CMD_PARAMS_STR.replace("${ctlPath}", ctlPath);
        StartTaskDto startTaskDto = new StartTaskDto();
        startTaskDto.setCmdParams(StringUtil.concat(new StringBuffer(),
                cmd_params_str, importSubTask.getSqlldrParams(),
                " userid=", importSubTask.getUsername(), "/", importSubTask.getPassword(), "@", importSubTask.getSid()));
        startTaskDto.setTnsUrl(importSubTask.getTnsUrl());

        try {
            //====================发起sqlldr访问====================
            Map<String, Object> result = handler.execution(
                    filePath,
                    ctlPath, filePath + "/" + datFileName,
                    importSubTask.getSqlldrUrl(),
                    startTaskDto);

            //获取log日志内容添加到msg字段
            String logFilePath = (String) result.get("filePath");
            if ("log".equals(FileUtil.getSuffix(logFilePath))) {
                String context = FileUtil.getFile(logFilePath, ExpConstants.GET_FILE_EXP);
                importTaskLog.setErrorMsg(context);
            }

            //当执行状态为false
            boolean resultFlag = (Boolean) result.get("flag");
            if (Boolean.FALSE.equals(resultFlag)) {
                //失败以后生成日志文件并更新flag
                importTaskLog.setFilePath(filePath);
                importTaskLog.setEndTime(new Date());
                importTaskLog.setTaskStatus(String.valueOf(TaskStatusEnum.FAIL.getCode()));
                Long subtaskId = importSubTask.getId();
                httpSupport.send(ReturnVo.ok()
                        .put("flag", "fail")
                        .put("id", subtaskId)
                        .put("importTaskLog", importTaskLog)
                );
                return false;
            }

            //============导入成功删除ctl导入文件，ctl文件删除成功后添加删除时间============
            if (resultFlag) {
                boolean isDelete = FileUtil.removeFile(filePath + "/file_ctl/", ctlFileName);
                if (isDelete) {
                    importTaskLog.setDeleteTime(new Date());
                }
            }
        } catch (Exception ignore) {
            //异常以后生成日志文件并更新flag
            importTaskLog.setFilePath(filePath);
            importTaskLog.setEndTime(new Date());
            importTaskLog.setTaskStatus(String.valueOf(TaskStatusEnum.FAIL.getCode()));
            importTaskLog.setErrorMsg(ExpConstants.IMPORT_EXP);
            Long subtaskId = importSubTask.getId();
            httpSupport.send(ReturnVo.ok()
                    .put("flag", "fail")
                    .put("id", subtaskId)
                    .put("importTaskLog", importTaskLog)
            );
            return false;
        }
        log.info("------ 导入成功 ------");
        return true;
    }
}